﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using SisGAC.Filters;
using SisGAC.Models;
using WebMatrix.WebData;

namespace SisGAC.Controllers
{
    [InitializeSimpleMembership]
    public class PessoasController : Controller
    {
        private SisgacContext db = new SisgacContext();

        //
        // GET: /Pessoas/
        [Authorize(Roles="Coordenador, Admin")]
        public ActionResult Index(bool autor = false)
        {
            //Retorna usuário logado
            int userid = WebSecurity.CurrentUserId;
            Pessoa pessoa = db.Pessoas.First(p => p.Account.UserId == userid);

            if (autor)
                ViewBag.Title = "Autores";
            else
                ViewBag.Title = "Pessoas";

            ViewBag.Autor = autor;

            if (autor)
                return View(db.Pessoas.Where(p => p.Autor == true).ToList());
            else
                return View(db.Pessoas.ToList());
        }

        //
        // GET: /Pessoas/Details/5
        [Authorize]
        public ActionResult Details(int id = 0)
        {
            Pessoa pessoa = new Pessoa();
            if (id == 0)
            {
                int userid = WebSecurity.CurrentUserId;
                if (userid != -1)
                    pessoa = db.Pessoas.First(p => p.Account.UserId == userid);
                else
                    return HttpNotFound();
            }
            else if (User.IsInRole("Coordenador"))
                pessoa = db.Pessoas.Find(id);
            else
                return RedirectToAction("AcessoNegado", "Home");

            if (pessoa == null)
            {
                return HttpNotFound();
            }
            return View(pessoa);
        }

        public ActionResult Cadastro(int id = 0, bool autor = false)
        {
            bool coordenador = User.IsInRole("Coordenador") || User.IsInRole("Admin");
            //Se não for coordenador, não pode cadastrar autor
            if (coordenador || autor == false)
            {
                Pessoa novaPessoa = new Pessoa();

                if (id > 0)
                {
                    novaPessoa = db.Pessoas.Find(id);
                    //Uma pessoa só pode editar o seu próprio cadastro, a não ser que seja coordenador
                    if (WebSecurity.CurrentUserId != novaPessoa.Account.UserId && !User.IsInRole("Coordenador") && !User.IsInRole("Admin"))
                        return RedirectToAction("AcessoNegado", "Home");
                    if (novaPessoa == null)
                        return HttpNotFound();
                }
                else
                {
                    novaPessoa.Autor = autor;
                    novaPessoa.Usuario = !autor;
                }

                if (coordenador)
                    ViewBag.TipoAcesso = 1;
                else
                    ViewBag.TipoAcesso = 0;

                return View(novaPessoa);
            }
            else
                return RedirectToAction("AcessoNegado", "Home");
        }

        [HttpPost]
        public ActionResult Cadastro(Pessoa pessoa)
        {
            if (ModelState.IsValid)
            {
                if (pessoa.Autor)
                    pessoa.DataNascimento = DateTime.Today;

                if (pessoa.PessoaId > 0)
                {
                    db.Entry(pessoa).State = EntityState.Modified;
                    db.SaveChanges();

                    //Redefine roles
                    RedefineRoles(pessoa.Coordenador, "Coordenador", pessoa.Account.UserName);
                    RedefineRoles(pessoa.Avaliador, "Avaliador", pessoa.Account.UserName);
                }
                else
                {
                    db.Pessoas.Add(pessoa);
                    db.SaveChanges();
                    if (pessoa.Usuario)
                    {
                        //Após cadastrar a pessoa, redireciona para tela de registro
                        return RedirectToAction("Register", "Account", new { id = pessoa.PessoaId, email = pessoa.Email });
                    }

                }

                return RedirectToAction("Index");
            }
            return View(pessoa);
            
        }

        private void RedefineRoles(bool adicionar, string role, string usuario)
        {
            if (adicionar)
            {
                if (!User.IsInRole(role))
                    Roles.AddUserToRole(usuario, role);
            }
            else
                if (User.IsInRole(role))
                    Roles.RemoveUserFromRole(usuario, role);
        }

        //
        // GET: /Pessoas/Delete/5
        [Authorize]
        public ActionResult Delete(int id = 0)
        {
            Pessoa pessoa = db.Pessoas.Find(id);
            if (pessoa == null)
            {
                return HttpNotFound();
            }

            //Uma pessoa só pode deletar o seu próprio cadastro, a não ser que seja coordenador
            if (WebSecurity.CurrentUserId != pessoa.Account.UserId && !User.IsInRole("Coordenador"))
                return RedirectToAction("AcessoNegado", "Home");

            return View(pessoa);
        }

        //
        // POST: /Pessoas/Delete/5
        [Authorize]
        [HttpPost, ActionName("Delete")]
        public ActionResult DeleteConfirmed(int id)
        {
            Pessoa pessoa = db.Pessoas.Find(id);
            db.Pessoas.Remove(pessoa);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        [Authorize(Roles="Coordenador")]
        public ActionResult AtribuirAreas(int id)
        {
            Pessoa pessoa = db.Pessoas.Find(id);
            if (pessoa == null)
                return HttpNotFound();

            if (!pessoa.Avaliador)
                return RedirectToAction("Index");

            PessoaAreasViewModel model = new PessoaAreasViewModel();
            model.PessoaId = id;
            model.Areas = new SelectList(db.Areas.ToList(), "AreaId", "Nome");
            model.AreasSelecionadas = pessoa.Areas.Select(a => a.AreaId).ToList();

            return View(model);
        }

        [HttpPost]
        [Authorize(Roles = "Coordenador")]
        public ActionResult AtribuirAreas(FormCollection form)
        {
            int id = Convert.ToInt32(form["PessoaId"]);

            Pessoa pessoa = db.Pessoas.Find(id);
            pessoa.Areas.Clear();

            string[] areas = form["AreasSelecionadas"].Split(',');
            List<Area> listAreas = new List<Area>();
            foreach (var s in areas)
            {
                int idArea = Convert.ToInt32(s);
                listAreas.Add(db.Areas.FirstOrDefault(a => a.AreaId == idArea));
            }

            pessoa.Areas = listAreas;

            db.SaveChanges();

            return RedirectToAction("Index");
        }

        //Exibe dados relevantes para o usuário logado
        [Authorize(Roles="Coordenador, Avaliador, Admin")]
        public ActionResult Dashboard()
        {
            Pessoa pessoa = db.Pessoas.FirstOrDefault(p => p.Account.UserId == WebSecurity.CurrentUserId);
            return View(pessoa);            
        }

        public JsonResult CPFDisponivel(string cpf, string CPFAtual)
        {
            if (cpf == CPFAtual)
                return Json(true, JsonRequestBehavior.AllowGet);

            if (db.Pessoas.Count(p => p.CPF == cpf) == 0)
                return Json(true, JsonRequestBehavior.AllowGet);

            return Json("CPF já cadastrado", JsonRequestBehavior.AllowGet);
        }

        [ChildActionOnly]
        public ActionResult InfoLogin()
        {
            Pessoa pessoa = new Pessoa();
            if (User.Identity.IsAuthenticated)
                pessoa = db.Pessoas.FirstOrDefault(p => p.Account.UserId == WebSecurity.CurrentUserId);
            return View(pessoa);
        }

        protected override void Dispose(bool disposing)
        {
            db.Dispose();
            base.Dispose(disposing);
        }
    }
}